<template>
  <div class="piano-audio-generator">
    <h2>钢琴音色生成</h2>
    <div class="control-group">
      <label for="frequency">基频 (Hz):</label>
      <input
        type="number"
        id="frequency" ref="frequencyInput"
        v-model.number="frequency"
        min="20"
        max="4000"
        step="1"
        placeholder="输入频率"
      >
      <button @click="generatePianoAudio" class="generate-btn">生成钢琴音频</button>
    </div>
    <div class="piano-keys">
      <button 
        v-for="note in notes" 
        :key="note.key" 
        :data-key="note.key"
        @click="playNote(note.frequency)"
        class="piano-key" :ref="`key-${note.key.replace(';', 'semicolon')}`"
      >
        {{ note.label }}
      </button>
    </div>
    <div v-if="audioUrl" class="audio-result">
      <h3>生成结果:</h3>
      <audio ref="audioPlayer" :src="audioUrl" controls class="audio-player" @error="handleAudioError" @loadeddata="playAudio"></audio>
      <a :href="audioUrl" download class="download-link">下载音频</a>
    </div>
    <div v-if="errorMessage" class="error-message">{{ errorMessage }}</div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      frequency: 440,
      audioUrl: null,
      errorMessage: '',
      notes: [
        { key: 'a', label: 'A', frequency: 261.63 },
        { key: 's', label: 'S', frequency: 293.66 },
        { key: 'd', label: 'D', frequency: 329.63 },
        { key: 'f', label: 'F', frequency: 349.23 },
        { key: 'g', label: 'G', frequency: 392.00 },
        { key: 'h', label: 'H', frequency: 440.00 },
        { key: 'j', label: 'J', frequency: 493.88 },
        { key: 'k', label: 'K', frequency: 523.25 },
        { key: 'l', label: 'L', frequency: 587.33 },
        { key: ';', label: ';', frequency: 659.25 }
      ]
    };
  },
  methods: {
    playNote(frequency) {
      this.frequency = frequency;
      this.generatePianoAudio();
      this.$el.focus();
    },
    handleKeydown(e) {
      const note = this.notes.find(n => n.key === e.key.toLowerCase());
      if (note) {
        e.preventDefault();
        this.playNote(note.frequency);
        const sanitizedKey = note.key.replace(';', 'semicolon');
      const button = this.$refs[`key-${sanitizedKey}`];
      console.log('按键触发:', note.key, '对应元素:', button);
        if (button) {
          button.classList.add('active');
          setTimeout(() => button.classList.remove('active'), 100);
        }
      }
    },
    playAudio() {
      try {
        this.$refs.audioPlayer.play();
      } catch (e) {
        console.warn('自动播放失败，可能需要用户交互:', e);
      }
    },
    handleAudioError(e) {
      this.errorMessage = `音频加载失败: ${e.target.error.message}`;
      console.error('音频错误详情:', e.target.error);
    },
    async generatePianoAudio() {
      this.$el.focus();
      this.errorMessage = '';
      try {
        const response = await axios.post('/api/piano/generate', {
          frequency: this.frequency
        });
        this.audioUrl = `http://localhost:3001${response.data.url}`;
      console.log('生成的音频URL:', this.audioUrl);
      this.$nextTick(() => {
        this.$refs.audioPlayer?.load();
        this.$el.focus();
      });
      } catch (err) {
        this.errorMessage = `生成失败: ${err.response?.data?.error || '未知错误'}\n详细信息: ${err.response?.data?.details || '无'}`;
        console.error('Axios 完整错误信息:', err);
          console.error('错误响应数据:', err.response);
          console.error('错误状态:', err.status);
          console.error('错误代码:', err.code);
      }
    }
  },
  mounted() {
      this.keydownHandler = this.handleKeydown.bind(this);
      window.addEventListener('keydown', this.keydownHandler);
    },
    beforeUnmount() {
      window.removeEventListener('keydown', this.keydownHandler);
    }
};
</script>

<style scoped>
.piano-audio-generator {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

.control-group {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 20px;
}

input {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  flex-grow: 1;
}

.generate-btn {
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  cursor: pointer;
  transition: background-color 0.3s;
}

generate-btn:hover {
  background-color: #359469;
}

audio-player {
  width: 100%;
  margin: 10px 0;
}

download-link {
  display: inline-block;
  margin-top: 10px;
  color: #42b983;
  text-decoration: none;
}

download-link:hover {
  text-decoration: underline;
}

error-message {
  color: #ff4444;
  margin-top: 10px;
  padding: 10px;
  background-color: #ffebee;
  border-radius: 4px;
}

.piano-keys {
  display: flex;
  gap: 8px;
  margin: 20px 0;
}

.piano-key {
  padding: 12px 0;
  flex: 1;
  background-color: #fff;
  border: 2px solid #42b983;
  border-radius: 6px;
  cursor: pointer;
  font-size: 18px;
  transition: all 0.1s ease;
}

.piano-key:hover {
  background-color: #f0f7f3;
}

.piano-key.active {
  background-color: #42b983;
  color: white;
  transform: scale(0.98);
}
</style>